package com.lianjia.sh.se.esb.server.config;

import com.dooioo.dymq.annotation.ActivemqListener;
import com.dooioo.dymq.listener.common.*;
import com.dooioo.plus.DyPlusConfig;
import com.lianjia.sh.se.esb.server.action.MessageAction;
import com.lianjia.sh.se.esb.server.annotation.MessageActionCfg;
import com.lianjia.sh.se.esb.spi.util.MessageUtil;
import org.apache.activemq.spring.ActiveMQConnectionFactory;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * spring容器刷新成功时，重新注册MQ队列Listener
 * Created by yangsp1 on 16/7/18.
 */
@Component
public class MQListenerRegister implements ApplicationContextAware {
    ApplicationContext applicationContext;

    @PostConstruct
    public void registerListeners(){
        //获取所有实现了MessageAction接口的对象
        Map<String,MessageAction> map = applicationContext.getBeansOfType(MessageAction.class);
        Iterator actions = map.keySet().iterator();

        //按projectType,serviceType注册 messageAction
        while(actions.hasNext()) {
            String key = (String)actions.next();
            MessageAction messageAction = map.get(key);
            MessageActionCfg messageActionCfg = messageAction.getClass().getAnnotation(MessageActionCfg.class);
            if(messageActionCfg == null){
                continue;
            }
            String projectType = messageActionCfg.MessageProjectType();
            Assert.isTrue(StringUtils.isNotBlank(projectType), "[" + messageAction.getClass().toString() + "]projectType不能为空");
            String serviceType = messageActionCfg.MessageServiceType();
            Assert.isTrue(StringUtils.isNotBlank(serviceType), "[" + messageAction.getClass().toString() + "]serviceType不能为空");
            registerListener(applicationContext,projectType,serviceType,messageAction);
        }
    }

    public void registerListener(ApplicationContext context,String projectType,String serviceType,MessageAction messageAction) {
        ConfigurableApplicationContext configurableApplicationContext = (ConfigurableApplicationContext)context;
        BeanDefinitionRegistry beanFactory = (BeanDefinitionRegistry)configurableApplicationContext.getBeanFactory();
        String beanName = null;
        Class registClazz = null;
        HashMap params = new HashMap();
        registClazz = TopicMessageListenerContainer.class;
        beanName = QueueMessageListenerContainer.class.getSimpleName() + "." + messageAction.getClass().getSimpleName() + "." + ActivemqListener.ActivemqMessageType.TOPIC;

        GenericBeanDefinition registBean = new GenericBeanDefinition();
        ActiveMQConnectionFactory inConnectionFactory = (ActiveMQConnectionFactory)context.getBean("activemq.in.connectionFactory", ActiveMQConnectionFactory.class);
        params.put("connectionFactory", inConnectionFactory);
        params.put("messageListener", messageAction);
        params.put("destinationName", MessageUtil.getMQName(projectType, serviceType,DyPlusConfig.getInstance().getEnv()));
        registBean.setBeanClass(registClazz);
        registBean.setPropertyValues(new MutablePropertyValues(params));
        beanFactory.registerBeanDefinition(beanName, registBean);

    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}
